#!/bin/python3

# encoding = 'utf-8'

import random
import time
import numpy as np

class Agent(object):
    landlord = 0
    farmer = 1
    def __init__(self, card_in_hand):
        self.card_in_hand = card_in_hand
        self.action_space = {}
        self._generate_action_space()
        self.type = Agent.farmer if len(card_in_hand) == 17 else Agent.landlord

    def _generate_action_space(self):
        # 单张出牌
        self.card_in_hand = np.sort(self.card_in_hand)
        self.action_space['single'] = []
        for card in self.card_in_hand:
            self.action_space['single'].append([card]) # 单张
        # 顺子出牌
        self.action_space['straight'] = []
        for card in self.card_in_hand:
            if card > 10:
                break
            seq = [card]
            next_card = card + 1
            while next_card <= 14 and next_card in self.card_in_hand:
                seq.append(next_card)
                if (len(seq) >= 5):
                    self.action_space['straight'].append(seq.copy()) # 顺子
                next_card += 1
        # 统计每张牌的数量
        count = {}
        for card in self.card_in_hand:
            count[card] = self.card_in_hand.tolist().count(card)

        # 三带一
        self.action_space['three_one'] = []
        for card in list(count.keys()):
            # 炸弹没有拆开出牌的道理
            if count[card] == 3:
                for next_card in list(count.keys()):
                    if next_card != card:
                        seq = [card, card, card, next_card]
                        self.action_space['three_one'].append(seq) # 三带一
        # 三带二
        self.action_space['three_two'] = []
        for card in list(count.keys()):
            if count[card] == 3:
                for next_card in list(count.keys()):
                    if next_card != card and count[next_card] >= 2:
                        seq = [card, card, card, next_card, next_card]
                        self.action_space['three_two'].append(seq) # 三带二
        # 四带二
        self.action_space['four_two'] = []
        for card in list(count.keys()):
            if count[card] == 4:
                for next_card in list(count.keys()):
                    if next_card != card:
                        for second_card in list(count.keys()):
                            if second_card != card and second_card != next_card:
                                seq = [card, card, card, card, next_card, second_card]
                                self.action_space['four_two'].append(seq) # 四带二
        # 炸弹
        self.action_space['bomb'] = []
        for card in list(count.keys()):
            if count[card] == 4:
                seq = [card, card, card, card]
                self.action_space['bomb'].append(seq) # 炸弹
        # 王炸
        self.action_space['king_bomb'] = []
        if 16 in self.card_in_hand and 17 in self.card_in_hand:
            seq = [16, 17]
            self.action_space['king_bomb'].append(seq) # 王炸
        # 对子出牌
        self.action_space['double'] = []
        for card in list(count.keys()):
            if count[card] >= 2:
                seq = [card, card]
                self.action_space['double'].append(seq) # 对子
        # 三连对子
        self.action_space['sequence_double'] = []
        for card in list(count.keys()):
            if card > 12:
                continue
            if count[card] >= 2:
                if card + 1 in list(count.keys()) and count[card + 1] >= 2:
                    if card + 2 in list(count.keys()) and count[card + 2] >= 2:
                        seq = [card, card, card + 1, card + 1, card + 2, card + 2]
                        self.action_space['sequence_double'].append(seq) # 三连对子
        return self.action_space

    def update_action_space(self, action:list):
        for card in action:
            self.card_in_hand.remove(card)
    
    def filter_with_rules(self, cards_showing: dict):
        # 牌的数量一致校验
        showing_type = cards_showing.keys()[0]

        # 更新所有action空间
        self._generate_action_space()

        variable_action_space = {}
        # 使用相同类型的action
        type_same_space = self.action_space[showing_type]
        if len(type_same_space) > 0:





    def get_action(self, obs: dict, sigma: float = 0.0):
        cards_in_box = obs['cards_in_box']
        cards_showing = obs['cards_showing']

        # 自己随便出牌, sigma平衡探索与利用
        action = dict()
        if cards_showing == None:
            if random.random() < sigma:
                total_keys = [ key for key in self.action_space.keys() if len(self.action_space[key]) > 0]
                type = random.choice(total_keys) 
                cards = random.choice(self.action_space[type])
                action = {type: cards}
            else:
                
            return action

        self.observe_station = []
        self.observe_station.extend(cards_in_box)
        self.observe_station.extend(cards_showing)
        self.observe_station.extend(cards_in_hand)




class Env(object):
    """
    环境类，用于模拟一个简单的扑克牌游戏环境。
    """
    def __init__(self):
        """
        初始化环境类。

        Args:
            position (list): 玩家位置列表，默认为[0, 1, 2], 分别代表地主、农民A和农民B
            按照该顺序出牌, 0抓底牌并先出牌
        """
        self.action_space = {}
        self.card_in_box = None
        self.observation_space = {"card_in_box": self.card_in_box}

    def reset(self, seed=None):
        if not seed:
            seed = random.seed(time.time())
        color = ['heart', 'spade', 'club', 'diamond']
        numbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
        jokes = [16, 17]
        card_in_box = []
        for i in numbers:
            for j in range(4):
                card_in_box.append(i)
        card_in_box.extend(jokes)

        random.shuffle(card_in_box)

        # 初始化每个agent的动作空间
        self.agents = []
        self.agents.append(Agent(card_in_box[:20]))
        self.agents.append(Agent(card_in_box[20:37]))
        self.agents.append(Agent(card_in_box[37:]))
        # 位置重排
        # random.shuffle(self.agents)

        # 初始化环境的状态
        self.card_in_box = []
    
    def step(self, actions):
        pass

if __name__ == '__main__':
    env = Env()
    env.reset()
    for agent in env.agents:
        print("agent type: ", agent.type, ", action_space: ", agent.action_space)
    
    # show_card_id = 0
    # while env.agents[show_card_id].card_in_hand > 0:
